#include <Ogre.h>

#include "OptionsState.h"
#include "IntroState.h"

using namespace Ogre;

OptionsState OptionsState::mOptionsState;

OptionsState::OptionsState() :
	mChatBox(0),
	spriteManager(0)
{
	mWindow = 0;
	mDebugOverlay = 0;
	displayCameraDetails = false;
	statsOn = false;
	mTimeUntilNextToggle = 0.0f;
}

void OptionsState::enter()
{
	mRoot = Root::getSingletonPtr();
	mWindow = mRoot->getAutoCreatedWindow();
	mDeviceManager = DeviceManager::getSingletonPtr();
	mDeviceManager->setBuffered(true);
	mGUIManager = GUIManager::getSingletonPtr();
	mKeyboard = mDeviceManager->mKeyboard;
	mMouse = mDeviceManager->mMouse;	
	mChatBox = ChatBox::getSingletonPtr();
	mChatBox->setFadeOn(true);

	// Set up Debug Overlay
	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");

	// Create SceneManager	
	mSceneMgr = mRoot->getSceneManager("plitzScene");

	// Create Camera
	mCamera = mSceneMgr->createCamera("OptionsCamera");

	// Create Viewport
	mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera);
	mViewport->setBackgroundColour(ColourValue(0.0, 0.0, 0.0));

	// Create Sprite Manager
	spriteManager=new Ogre2dManager;
	spriteManager->init(mSceneMgr, Ogre::RENDER_QUEUE_OVERLAY, true);
	

	// Create Sound Manager
	// soundManager = new OgreAL::SoundManager();
	soundManager = OgreAL::SoundManager::getSingletonPtr();
	
	// Playing music
	sound = soundManager->createSound("Others", "Others.ogg", true);
	sound->setGain(Config::BGSOUNDLEVEL);
	sound->play();

	// Reigster GUI Items
	mGUIManager->registerScene(mSceneMgr);
	mGUIManager->setGUISheet(CEGUI::WindowManager::getSingletonPtr()->getWindow("Options/Sheet"));
	
	setupEventHandlers();

	// Set default values for each entry
	mGoBack = false;	
}

void OptionsState::exit()
{
	// Removing Game GUI
	mChatBox->clear();
	spriteManager->end();
	delete spriteManager;

	// Removing sound
	sound->stop();
	soundManager->destroySound(sound);

	// Switch off debug overlays
	displayCameraDetails = false;
	statsOn = false;
	mDebugOverlay->hide();

	mSceneMgr->clearScene();
	mSceneMgr->destroyAllCameras();
	mRoot->getAutoCreatedWindow()->removeAllViewports();
}

void OptionsState::pause()
{
}

void OptionsState::resume()
{
}

bool OptionsState::keyPressed(const OIS::KeyEvent &arg)
{
	if (arg.key == OIS::KC_B || arg.key == OIS::KC_ESCAPE)	// B to Back
		mGoBack = true;

	// Toggle Debug Overlay
	if (arg.key == OIS::KC_F1 && mTimeUntilNextToggle <= 0 && Config::getInstance()->cfg_debugOn)
	{
		statsOn = !statsOn;
		mTimeUntilNextToggle = 0.5;
		if (statsOn) mDebugOverlay->show();
		else mDebugOverlay->hide();
	}

	// ChatBox keys
	if (arg.key == OIS::KC_Y && mTimeUntilNextToggle <= 0)
	{
		mChatBox->addText("You pressed the 'Y' Key in Options State.");
		mTimeUntilNextToggle = 0.3;
	}
	if (arg.key == OIS::KC_U && mTimeUntilNextToggle <= 0)
	{
		mChatBox->addText("You pressed the 'U' Key in Options State.");
		mTimeUntilNextToggle = 0.3;
	}

	return true;
}

bool OptionsState::keyReleased(const OIS::KeyEvent &arg)
{
	return true;
}

bool OptionsState::mouseMoved( const OIS::MouseEvent &arg )
{
	CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
	mDeviceManager->mMouseCursor->updatePosition(arg.state.X.abs,arg.state.Y.abs);
	return true;
}

bool OptionsState::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
	return true;
}

bool OptionsState::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
	return true;
}

bool OptionsState::frameStarted(const FrameEvent& evt)
{
	// Update toggle buffering time
	if (mTimeUntilNextToggle >= 0)
				mTimeUntilNextToggle -= evt.timeSinceLastFrame;

	// Updating debug overlay stats
	updateStats();

	// Update chatbox
	mChatBox->loop(evt.timeSinceLastFrame);

	drawSprites();

	// Update Settings
	
	char str[32]; 
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *music = wmgr->getWindow((CEGUI::utf8*)"Options/Music");
	CEGUI::Slider *m = static_cast<CEGUI::Slider*> (music);
	Config::BGSOUNDLEVEL = 2 * m->getCurrentValue();
	sound->setGain(Config::BGSOUNDLEVEL);
    CEGUI::Window *mfont = wmgr->getWindow((CEGUI::utf8*)"Options/MusicFont");
	sprintf(str,"%i", int(m->getCurrentValue() * 100)); 
	mfont->setText(str);

    CEGUI::Window *sound = wmgr->getWindow((CEGUI::utf8*)"Options/Sound");
	CEGUI::Slider *s = static_cast<CEGUI::Slider*> (sound);
	Config::SOUNDFXLEVEL = 2 * s->getCurrentValue();
    CEGUI::Window *sfont = wmgr->getWindow((CEGUI::utf8*)"Options/SoundFont");
	sprintf(str,"%i", int(s->getCurrentValue() * 100)); 
	sfont->setText(str);

    CEGUI::Window *round = wmgr->getWindow((CEGUI::utf8*)"Options/Round");
	CEGUI::Slider *r = static_cast<CEGUI::Slider*> (round);
	Config::NUMOFROUNDS = int(r->getCurrentValue())+1;
    CEGUI::Window *rfont = wmgr->getWindow((CEGUI::utf8*)"Options/RoundFont");
	sprintf(str,"%i", int(r->getCurrentValue())+1); 
	rfont->setText(str);

	if (mKeyboard) 
		mKeyboard->capture();
	if (mMouse)
		mMouse->capture();
	return true;
}

bool OptionsState::frameEnded(const FrameEvent& evt)
{
	if (mGoBack)
		changeState(IntroState::getInstance());
	return true;
}

void OptionsState::createScene()
{
}

void OptionsState::setupEventHandlers()
{
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *back = wmgr->getWindow((CEGUI::utf8*)"Options/BackButton");
	back->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&OptionsState::handleBack, this));

	/*CEGUI::Window *mapSelect = wmgr->getWindow((CEGUI::utf8*)"Net/MapSelect");
	mapSelect->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted, 
				CEGUI::Event::Subscriber(&OptionsState::handleMapSelection, this));*/
}

bool OptionsState::handleBack(const CEGUI::EventArgs& e)
{
	mGoBack = true;
	return true;
}
/*
bool OptionsState::handleMapSelection(const CEGUI::EventArgs& e)
{
	const CEGUI::WindowEventArgs& windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>(e);
    CEGUI::ListboxItem* item = static_cast<CEGUI::Combobox*>(windowEventArgs.window)->getSelectedItem();
	switch(item->getID())
    {
        case 0:
			Config::getInstance()->LEVEL = "SpaceDock.scene";
            break;
        case 1:
            Config::getInstance()->LEVEL = "stonehenge.scene";
            break;
		default:
			Config::getInstance()->LEVEL = "SpaceDock.scene";
			break;
	};
	
	return true;
}
*/
void OptionsState::drawSprites()
{
}